import { Computed, Mut, VueService } from "vue3-oop";
import { WidgetNode, ReserveItem } from './index'
import { createProps } from '../widgets'
import FlexProps from '../widgets/layouts/flex/FlexProps'

export default class FormData extends VueService {
  // 表单大小 暂时用不到
  @Mut() formSize = 'mini';
  // 浏览器窗口大小
  @Mut() winSize = 'xs' as 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'xxxl';
  // key是widgetId，value是WidgetNode
  @Mut() nodeMap = new Map<string, WidgetNode>();
  // WidgetNode的树形结构
  @Mut() nodeTree = {} as WidgetNode;
  // 选中的组件widgetId
  @Mut() private selectedWidgetId = '';

  constructor() {
    super();
    this.init();
  }

  /**
   * 初始化
   */
  init = (): void => {
    const rootProps = new FlexProps({widgetId: "ROOT", gaps:{x:10,y:10}});

    const rootNode = new WidgetNode({
      formData: this,
      widgetId: rootProps.widgetId,
      widgetType: rootProps.widgetType,
      widgetProps: rootProps
    });
    this.nodeMap.set(rootNode.widgetId, rootNode);
    this.nodeTree = rootNode;
  }

  /**
   * 清除根节点外的其他所有子孙节点
   */
  clear =():void=>{
    const rootWidgetNode = this.nodeMap.get('ROOT') as WidgetNode;
    this.nodeMap.clear();
    this.nodeMap.set(rootWidgetNode.widgetId, rootWidgetNode);
    this.nodeTree.children = []
  }

  /**
   * 计算窗口尺寸
   */
  loadWinSize = (): void => {
    const winWidth = window.document.body.clientWidth
    let winSize = 'xs'
    winSize = winWidth >= 576 ? 'sm' : winSize;
    winSize = winWidth >= 768 ? 'md' : winSize;
    winSize = winWidth >= 992 ? 'lg' : winSize;
    winSize = winWidth >= 1200 ? 'xl' : winSize;
    winSize = winWidth >= 1600 ? 'xxl' : winSize;
    winSize = winWidth >= 2000 ? 'xxxl' : winSize;
    this.winSize = winSize as any;
  }

  /**
   * 选中的组件Props
   */
  @Computed() get selectedWidgetProps(){
    return this.nodeMap.get(this.selectedWidgetId)?.widgetProps
  }

  // /**
  //  * 输入型组件的字段编码和WidgetItem的MAP
  //  */
  // @Computed() get codeItemMap(){
  //   const codeItemMap = new Map<string,WidgetProps>();
  //   this.nodeMap.forEach((wigetNode:WidgetNode)=>{
  //     const { widgetProps } = wigetNode;
  //     const attr = (widgetProps as any)[widgetItem.type];
  //     if(attr.field_code){
  //       codeItemMap.set(attr.field_code,widgetItem);
  //     }
  //   });
  //   return codeItemMap;
  // }

  // /**
  //  * 输入型组件的字段编码和值的Object
  //  */
  // @Computed() get codeValueObj(){
  //   const codeValueObj = {} as any;
  //   this.nodeMap.forEach((wigetNode:WidgetNode)=>{
  //     const { widgetProps } = wigetNode;
  //     if(widgetItem.setValue instanceof Function){
  //       widgetItem.setValue();
  //     }
  //     const attr = (widgetItem as any)[widgetItem.type];
  //     if(attr.field_code){
  //       codeValueObj[attr.field_code] = {
  //         type: widgetItem.type,
  //         code: attr.field_code,
  //         label: attr.field_label,
  //         value: attr.field_value,
  //         format: attr.field_format
  //       };
  //     }
  //   });
  //   return codeValueObj;
  // }

  // @Computed() get formModel(){
  //   const formModel = {} as any;
  //   this.nodeMap.forEach((wigetNode:WidgetNode)=>{
  //     const { widgetItem } = wigetNode;
  //     const attr = (widgetItem as any)[widgetItem.type];
  //     if(attr.field_code){
  //       formModel[attr.field_code] = attr.field_value;
  //     }
  //   });
  //   return formModel;
  // }

  /**
   * 设置选中组件的ID
   * @param widgetId 选中的ID
   */
  setSelectedWidgetId=(widgetId:string)=>{
    // 将点击项的id赋值给 selectedWidgetId 用于判定是否选中
    if(widgetId&&widgetId!=='ROOT'){// 最最外层的草稿 GRID 无法选中
      this.selectedWidgetId = widgetId;
    }
  }

  /**
   * 判断是否是选中组件的ID
   * @param widgetId 判断的ID
   */
  isSelectedWidgetId=(widgetId:string):boolean=>{
    return this.selectedWidgetId===widgetId
  }

  /**
   * 获取FormData的JSON表达数据
   */
  getJsonData=():Object=>{
    const { formSize, winSize } = this;
    const nodeTreeToJson=(widgetNode:WidgetNode):Object=>{
      const { parentId, widgetId, widgetType } = widgetNode;
      const widgetProps = JSON.parse(JSON.stringify(widgetNode.widgetProps))
      const children = widgetNode.children.map((childNode:WidgetNode)=>nodeTreeToJson(childNode));
      return { parentId, widgetId, widgetType: widgetType, widgetProps, children }
    }
    const nodeTree = nodeTreeToJson(this.nodeTree);
    return { formSize, winSize, nodeTree }
  }

  /**
   * 从JSON数据加载FormData
   * @param jsonData 从方法 getJsonData 获取的JSON数据
   */
  loadFromJsonData=(jsonData:any):void=>{
    this.clear();
    this.formSize = jsonData.formSize;
    this.winSize = jsonData.winSize;

    const jsonToNodeTree=(jsonTree:any)=>{
      const { parentId, widgetId, widgetType } = jsonTree;
      const widgetProps = createProps(undefined as any, widgetType as any, jsonTree.widgetProps);
      const widgetNode = new WidgetNode({formData:this,parentId,widgetId,widgetType,widgetProps});
      widgetNode.children = jsonTree.children.map((childNode:any)=>jsonToNodeTree(childNode)) as WidgetNode[];
      this.nodeMap.set(widgetId,widgetNode);
      return widgetNode;
    }
    this.nodeTree = jsonToNodeTree(jsonData.nodeTree);
  }

  /**
   * 新增组件节点
   * @param parentNode 父节点NODE
   * @param reserveItem 待添加组件的简略信息
   * @param index
   */
  createNewWidgetNode=(parentNode:WidgetNode,reserveItem:ReserveItem,index:number)=>{
    const parentProps = parentNode.widgetProps;

    const newWidgetProps = createProps(parentProps,reserveItem.type as any);

    const newWidgetNode = new WidgetNode({
      formData: this,
      parentId: parentNode.widgetId,
      widgetId: newWidgetProps.widgetId,
      widgetType: newWidgetProps.widgetType,
      widgetProps: newWidgetProps
    });

    parentNode.children[index] = newWidgetNode;
    this.nodeMap.set(newWidgetNode.widgetId,newWidgetNode);
    this.setSelectedWidgetId(newWidgetNode.widgetId);
  }

}